﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Web;

namespace OPCService.Service
{
    class HttpService: IDisposable
    {
        private readonly HttpClient _httpClient;
        private readonly JsonSerializerOptions _jsonOptions;

        public HttpService(string baseAddress, int timeoutSeconds = 30)
        {
            _httpClient = new HttpClient
            {
                BaseAddress = new Uri(baseAddress),
                Timeout = TimeSpan.FromSeconds(timeoutSeconds)
            };

            _httpClient.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

            _jsonOptions = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
                WriteIndented = false
            };
        }

        // 设置认证令牌
        public void SetBearerToken(string token)
        {
            _httpClient.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", token);
        }

        // 添加自定义请求头
        public void AddHeader(string name, string value)
        {
            if (_httpClient.DefaultRequestHeaders.Contains(name))
                _httpClient.DefaultRequestHeaders.Remove(name);

            _httpClient.DefaultRequestHeaders.Add(name, value);
        }

        // 核心请求方法（支持所有参数类型）
        public async Task<T> SendRequestAsync<T>(
            HttpMethod method,
            string endpoint,
            object body = null,
            Dictionary<string, string> queryParams = null,
            Dictionary<string, string> formData = null,
            List<KeyValuePair<string, Stream>> fileParams = null)
        {
            try
            {
                // 处理查询参数
                endpoint = AppendQueryParams(endpoint, queryParams);

                var request = new HttpRequestMessage(method, endpoint);

                // 处理请求体（JSON/FormData/文件）
                if (body != null || formData != null || fileParams != null)
                {
                    request.Content = CreateContent(body, formData, fileParams);
                }

                var response = await _httpClient.SendAsync(request);
                return await HandleResponse<T>(response);
            }
            catch (TaskCanceledException)
            {
                throw new HttpRequestException("请求超时");
            }
            catch (Exception ex)
            {
                throw new HttpRequestException($"请求失败: {ex.Message}");
            }
        }

        // 处理查询参数
        private string AppendQueryParams(string endpoint, Dictionary<string, string> queryParams)
        {
            if (queryParams == null || !queryParams.Any())
                return endpoint;

            var queryString = string.Join("&",
                queryParams.Select(kv =>
                    $"{WebUtility.UrlEncode(kv.Key)}={WebUtility.UrlEncode(kv.Value)}"));

            return $"{endpoint}?{queryString}";
        }

        // 创建请求内容
        private HttpContent CreateContent(
            object body,
            Dictionary<string, string> formData,
            List<KeyValuePair<string, Stream>> fileParams)
        {
            // 1. 文件上传（多部分表单）
            if (fileParams != null && fileParams.Any())
            {
                var multipartContent = new MultipartFormDataContent();

                // 添加文件
                foreach (var fileParam in fileParams)
                {
                    var fileContent = new StreamContent(fileParam.Value);
                    multipartContent.Add(fileContent, fileParam.Key, "file");
                }

                // 添加表单字段
                if (formData != null)
                {
                    foreach (var kv in formData)
                    {
                        multipartContent.Add(new StringContent(kv.Value), kv.Key);
                    }
                }

                return multipartContent;
            }

            // 2. 普通表单数据
            if (formData != null)
            {
                return new FormUrlEncodedContent(
                    formData.Select(kv => new KeyValuePair<string, string>(kv.Key, kv.Value)));
            }

            // 3. JSON主体
            var json = JsonSerializer.Serialize(body, _jsonOptions);
            return new StringContent(json, Encoding.UTF8, "application/json");
        }

        // 处理响应（保持不变）
        private async Task<T> HandleResponse<T>(HttpResponseMessage response)
        {
            var content = await response.Content.ReadAsStringAsync();

            if (!response.IsSuccessStatusCode)
            {
                throw new HttpRequestException(
                    $"HTTP错误: {response.StatusCode}\n响应内容: {content}");
            }

            // 处理空响应
            if (string.IsNullOrWhiteSpace(content))
            {
                if (typeof(T) == typeof(bool)) return (T)(object)true;
                return default;
            }

            try
            {
                return JsonSerializer.Deserialize<T>(content, _jsonOptions);
            }
            catch (JsonException)
            {
                throw new HttpRequestException($"JSON解析失败: {content}");
            }
        }

        // 快捷方法（添加参数支持）
        public Task<T> GetAsync<T>(string endpoint,
            Dictionary<string, string> queryParams = null) =>
            SendRequestAsync<T>(HttpMethod.Get, endpoint, null, queryParams);

        public Task<T> PostAsync<T>(string endpoint,
            object body = null,
            Dictionary<string, string> formData = null) =>
            SendRequestAsync<T>(HttpMethod.Post, endpoint, body, null, formData);

        public Task<T> PostFileAsync<T>(string endpoint,
            List<KeyValuePair<string, Stream>> files,
            Dictionary<string, string> formData = null) =>
            SendRequestAsync<T>(HttpMethod.Post, endpoint, null, null, formData, files);

        public Task<T> PutAsync<T>(string endpoint, object body) =>
            SendRequestAsync<T>(HttpMethod.Put, endpoint, body);

        public Task<T> DeleteAsync<T>(string endpoint,
            Dictionary<string, string> queryParams = null) =>
            SendRequestAsync<T>(HttpMethod.Delete, endpoint, null, queryParams);

        public void Dispose() => _httpClient?.Dispose();
    }
}
